#include "simulate_error.h"
#include "timestamp.h"
#include "dbg_trace.h"
#include "com_print.h"
#include "stm32wbxx_hal.h"


#define WWDG_WINDOW    0x7F
#define WWDG_COUNTER   0x7F
WWDG_HandleTypeDef hwwdg;


static volatile int HardFault_error_simulate_A(uint32_t a)
{
  uint32_t *paddr = (uint32_t*)0x33333333;
	// // Trigger a hardware fault
  *paddr = 12345+a;
	//COMPrintf("HardFault_error_simulate %d %d ", *paddr, a); 
  return a;  
}


static void HardFault_error_simulate_B(uint32_t b)
{
	 HardFault_error_simulate_A(b);
}

static void HardFault_error_simulate_C(uint32_t c)
{
	COMPrintf("*");
  HardFault_error_simulate_B(c);
}

static void HardFault_error_simulate_D(uint32_t d)
{
	COMPrintf("*");
  HardFault_error_simulate_C(d);
}


static void HardFault_error_simulate(void)
{
  HardFault_error_simulate_D(1234);
}

/**
  * @brief WWDG Initialization Function
  * @param None
  * @retval None
  */
static void MX_WWDG_Init(void) 
{
	
	  __HAL_RCC_WWDG_CLK_SLEEP_ENABLE();
    hwwdg.Instance = WWDG;
    hwwdg.Init.Prescaler = WWDG_PRESCALER_128;
    hwwdg.Init.Window = WWDG_WINDOW;
    hwwdg.Init.Counter = WWDG_COUNTER;
    hwwdg.Init.EWIMode = WWDG_EWI_ENABLE;  // ?? EWI ??

    if (HAL_WWDG_Init(&hwwdg) != HAL_OK) {
        COMPrintf("HAL_WWDG_Init error \r\n");
    }

		HAL_NVIC_SetPriority(WWDG_IRQn, 0, 0);   // ???????
    HAL_NVIC_EnableIRQ(WWDG_IRQn);           // ?? WWDG ??
		
    
    COMPrintf("MX_WWDG_Init\r\n");
}


static uint32_t TimeoutCalculation(uint32_t timevalue)
{
  uint32_t timeoutvalue = 0;
  uint32_t pclk1 = 0;
  uint32_t wdgtb = 0;

  /* considering APB divider is still 1, use HCLK value */
  pclk1 = HAL_RCC_GetPCLK1Freq();

  /* get prescaler */
  wdgtb = (1 << ((hwwdg.Init.Prescaler) >> WWDG_CFR_WDGTB_Pos)); /* 2^WDGTB[1:0] */

  /* calculate timeout */
  timeoutvalue = ((4096 * wdgtb * timevalue) / (pclk1 / 1000));

  return timeoutvalue;
}



static void WDG_error_simulate(void)
{
	HAL_Delay(5000);
}


void simulate_error_tick(void)
{
  static uint64_t last_timestamp = 0;
	uint64_t cur_timestamp = RTC_GetTimestampMillis();
	if(cur_timestamp > last_timestamp + 1000){
		last_timestamp = cur_timestamp;
		COMPrintf("cur_timestamp:%lld \r\n", cur_timestamp);
		static uint32_t s_count = 0;
		s_count++;
		if(s_count == 5){
			//HardFault_error_simulate();
		  WDG_error_simulate();
		}
		
	}
	//HAL_WWDG_Refresh(&hwwdg);
	static uint8_t init_flag = 0;
	if(init_flag == 0){
		init_flag = 1;
		MX_WWDG_Init();
	}
	
	HAL_WWDG_Refresh(&hwwdg);

}









